package com.example.kotlindemo.pages

import android.os.Bundle
import android.transition.Slide
import android.transition.TransitionManager
import android.view.Gravity
import android.view.View
import android.widget.EditText
import android.widget.FrameLayout
import android.widget.LinearLayout
import androidx.activity.enableEdgeToEdge
import androidx.activity.viewModels
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.updateLayoutParams
import com.example.kotlindemo.R
import com.example.kotlindemo.modules.todolist.CompletedTasksFragment
import com.example.kotlindemo.modules.todolist.PendingTasksFragment
import com.example.kotlindemo.modules.todolist.TodoListViewModel
import com.google.android.material.floatingactionbutton.FloatingActionButton

// Mvvm架构模式
// 1. 封装Model层(数据源)，网络请求或本地Room数据库
// 1.1 声明数据返回类型采用 LiveData (支持响应式更新)
// 1.2 对数据进行逻辑抽离，单独进行增、删、改、查方法封装
// 2. 封装ViewModel UI和数据逻辑层，对应UI和数据的逻辑关系
// 2.1 封装对Model层中最终数据逻辑方法的引用
// 2.2 暴露对UI层的方法，处理用户交互
// 2.3 使用协程 viewModelScope.launch 来进行异步操作，避免主线程阻塞
// 3. 封装View层
// 3.1 初始化并对 viewModel 目标数据进行监听或者订阅 observe
// 3.2 封装处理UI逻辑的方法，发生交互时，调用该方法或适配器 adapter
// 3.3 适配器中封装使用 ListAdapter 的 DiffUtil（TaskDiffCallback）计算数据差异，高效更新 RecyclerView。

// 几个关键点：
// 1。LiveData：Room 的 LiveData 查询（如 getPendingTasks）会自动监听数据库变化，当数据更新时通知观察者。
// 2. ListAdapter：通过 DiffUtil 高效比较新旧数据，仅更新变化的部分，避免整个列表刷新。
// 3. ViewModelScope：确保数据库操作异步执行，不会阻塞 UI 线程。
// 4. Fragment 的 LifecycleOwner：observe(viewLifecycleOwner) 确保 LiveData 仅在 Fragment 可见时更新，避免内存泄漏。

// 整体流程：
// 初始化：
// AppDatabase -> TaskDao -> TaskRepository -> TodoListViewModel -> PendingTasksFragment。
// LiveData 从数据库查询绑定到 Fragment 的 RecyclerView。
// 用户操作：
// 用户交互（如点击完成） -> Fragment -> ViewModel -> Repository -> TaskDao -> 数据库。
// 数据库更新触发 LiveData 变化 -> ViewModel -> Fragment -> Adapter -> RecyclerView。
// 响应式更新：
// Room 的 LiveData 自动监听数据库变化。
// Fragment 观察 ViewModel 的 LiveData，调用 ListAdapter 更新 UI。


class TodoListActivity : AppCompatActivity() {
    // 使用 viewModels 委托获取 ViewModel 实例
    private val viewModel: TodoListViewModel by viewModels()
    // 使用 lateinit 和 findViewById
    private lateinit var fabAddTask: FloatingActionButton
    private lateinit var completedTasksContainer: FrameLayout
    private lateinit var pendingTasksContainer: FrameLayout
    private lateinit var contentContainer: LinearLayout // 父容器，用于 TransitionManager

    private var isCompletedFragmentAdded = false // 标记完成 Fragment 是否已添加

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_todo_list)
        enableEdgeToEdge()

        // 初始化视图
        fabAddTask = findViewById(R.id.fabAddTask)
        completedTasksContainer = findViewById(R.id.completedTasksContainer)
        pendingTasksContainer = findViewById(R.id.pendingTasksContainer)
        contentContainer = findViewById(R.id.contentContainer)

        setupFab()
        loadInitialFragment()
        observeViewModel()
    }

    private fun setupFab() {
        fabAddTask.setOnClickListener {
            showAddTaskDialog()
        }
    }

    // 加载初始的待办任务 Fragment
    private fun loadInitialFragment() {
        if (supportFragmentManager.findFragmentById(R.id.pendingTasksContainer) == null) {
            supportFragmentManager.beginTransaction()
                .replace(R.id.pendingTasksContainer, PendingTasksFragment.newInstance())
                .commit()
        }
    }

    private fun observeViewModel() {
        // 观察是否有已完成任务，用于控制 CompletedTasksFragment 的显隐和动画
        viewModel.hasCompletedTasks.observe(this) { hasCompleted ->
            toggleCompletedTasksVisibility(hasCompleted)
        }

        // (可选) 观察 LiveData 以显示 SnackBar 或 Toast 提示
        // viewModel.someEvent.observe(this, EventObserver { message -> ... })
    }

    // 控制“完成清单”区域的显示/隐藏及动画
    private fun toggleCompletedTasksVisibility(show: Boolean) {
        val fragmentManager = supportFragmentManager
        val completedFragment = fragmentManager.findFragmentById(R.id.completedTasksContainer)

        // 计算动画前 pendingTasksContainer 的目标 marginTop
        val targetMarginTop = if (show) resources.getDimensionPixelSize(R.dimen.pending_list_margin_top_when_completed_visible) else 0

        // 使用 TransitionManager 实现动画过渡
        // 注意：TransitionManager 对 Fragment 的 add/remove 动画效果有限，
        // 主要作用于布局属性变化（如 visibility, margin）
        val transition = Slide(Gravity.BOTTOM).apply {
            addTarget(pendingTasksContainer) // 只对 pendingTasksContainer 应用动画
            duration = 300 // 动画时长
        }
        TransitionManager.beginDelayedTransition(contentContainer, transition)


        if (show && completedFragment == null) {
            // 需要显示，且 Fragment 未添加
            completedTasksContainer.visibility = View.VISIBLE
            fragmentManager.beginTransaction()
                .replace(R.id.completedTasksContainer, CompletedTasksFragment.newInstance())
                .commitNowAllowingStateLoss() // 使用 commitNow 确保 Fragment 立即可用
            isCompletedFragmentAdded = true
            // 更新 pendingTasksContainer 的 marginTop
            pendingTasksContainer.updateLayoutParams<LinearLayout.LayoutParams> {
                topMargin = targetMarginTop
            }

        } else if (!show && completedFragment != null) {
            // 需要隐藏，且 Fragment 已添加
            completedTasksContainer.visibility = View.GONE
            fragmentManager.beginTransaction()
                .remove(completedFragment)
                .commitNowAllowingStateLoss()
            isCompletedFragmentAdded = false
            // 更新 pendingTasksContainer 的 marginTop
            pendingTasksContainer.updateLayoutParams<LinearLayout.LayoutParams> {
                topMargin = targetMarginTop
            }
        } else {
            // 如果 Fragment 状态和 show 状态一致，仅确保 visibility 和 margin 正确
            // (防止配置更改等导致状态不一致)
            completedTasksContainer.visibility = if (show) View.VISIBLE else View.GONE
            pendingTasksContainer.updateLayoutParams<LinearLayout.LayoutParams> {
                topMargin = targetMarginTop
            }
        }
    }


    // 显示添加任务的对话框
    private fun showAddTaskDialog() {
        val editText = EditText(this).apply {
            hint = getString(R.string.enter_task_name_hint)
        }
        AlertDialog.Builder(this)
            .setTitle(R.string.add_new_task_title)
            .setView(editText)
            .setPositiveButton(R.string.add) { dialog, _ ->
                val taskName = editText.text.toString().trim()
                if (taskName.isNotEmpty()) {
                    viewModel.addNewTask(taskName)
                }
                dialog.dismiss()
            }
            .setNegativeButton(R.string.cancel) { dialog, _ ->
                dialog.cancel()
            }
            .show()
    }
}